package com.uum.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.uum.blog.pojo.entity.Blog;
import com.uum.blog.pojo.entity.Comment;
import com.uum.blog.mapper.CommentMapper;
import com.uum.blog.pojo.entity.CommentLike;
import com.uum.blog.pojo.form.BlogForm;
import com.uum.blog.pojo.vo.CommentVO;
import com.uum.blog.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.uum.web.exception.BizException;
import com.uum.web.util.JwtUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    private final BlogService blogService;
    private final EsBlogService esBlogService;
    private final RedisService redisService;
    private final CommentLikeService commentLikeService;

    @Override
    public List<CommentVO> listComment(Long blogId) {
        List<CommentVO> allComment = baseMapper.listComment(new QueryWrapper<Comment>().eq("t1.blog_id", blogId).orderByDesc("t1.create_time"));
        List<CommentVO> commentWithTree = allComment.stream()
                .filter(comment -> comment.getParentId() == 0)
                .map(comment -> {
                    comment.setReplyList(getChildren(comment, allComment));
                    return comment;
                })
                .collect(Collectors.toList());
        for (CommentVO comment : commentWithTree) {       //加上redis中的点赞数量
            Long redis = redisService.countLike(comment.getCommentId());
            if (redis != 0) {
                comment.setLikeCount(comment.getLikeCount() + Integer.valueOf(String.valueOf(redis)));
                Set userLike = redisService.listLike(comment.getCommentId());
                comment.setUserLikeCollection(userLike);
            }
        }
        return commentWithTree;
    }

    private List<CommentVO> getChildren(CommentVO current, List<CommentVO> all) {
        List<CommentVO> childrenList = all.stream()
                .filter(a -> a.getParentId().equals(current.getCommentId()))
                .map(a -> {
                     a.setReplyList(getChildren(a, all));
                     return a;
                })
                .collect(Collectors.toList());
        return childrenList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<CommentVO> deleteComment(Long commentId, Long blogId) {
        List<CommentVO> commentList = new ArrayList<>();
        //查询出该评论下的所有子评论
        List<Comment> allComment = baseMapper.selectList(new LambdaQueryWrapper<Comment>().eq(Comment::getBlogId, blogId));
        List<Comment> collect = allComment.stream()
                .filter(item -> item.getCommentId() == commentId)
                .map(item -> item.setReplyList(getChildren(item, allComment)))
                .collect(Collectors.toList());
        List<Long> deleteIdList = new ArrayList<>();
        Comment comment = collect.get(0);
        deleteIdList.add(comment.getCommentId());
        findAllId(comment.getReplyList(), deleteIdList);
        //删除所有评论包括子评论
        int result = baseMapper.deleteBatchIds(deleteIdList);
        if (result > 0) {
            //删除点赞评论
            commentLikeService.remove(new LambdaQueryWrapper<CommentLike>().in(CommentLike::getCommentId, deleteIdList));
            //删除redis中的点赞评论
            redisService.deleteComment(commentId);
            commentList = updateCommentCount(blogId);
        }
        return commentList;
    }

    private List<Comment> getChildren(Comment current, List<Comment> all) {
        List<Comment> childrenList = all.stream()
                .filter(a -> a.getParentId().equals(current.getCommentId()))
                .map(a -> a.setReplyList(getChildren(a, all)))
                .collect(Collectors.toList());
        return childrenList;
    }

    /**
     * 获取树中的所有commentId
     *
     * @param comment
     * @param deleteIdList
     */
    private void findAllId(List<Comment> comment, List<Long> deleteIdList) {
        for (Comment children : comment) {
            deleteIdList.add(children.getCommentId());
            if (!children.getReplyList().isEmpty()) {
                findAllId(children.getReplyList(), deleteIdList);
            }
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<CommentVO> addComment(Comment comment) {
        //判断该博文是否开启评论
        Blog blog = blogService.getById(comment.getBlogId());
        if (blog.getIsComment() != 1) {
            throw new BizException("本篇博文没有开启评论功能");
        }
        comment.setFromId(JwtUtils.getUserId());
        List<CommentVO> commentList = new ArrayList<>();
        int insert = baseMapper.insert(comment);
        if (insert > 0) {
            commentList = updateCommentCount(comment.getBlogId());
        }
        return commentList;
    }


    /**
     * 更新评论数量
     *
     * @param blogId
     * @return
     */
    private List<CommentVO> updateCommentCount(Long blogId) {
        //查询该博文下的评论数量
        Integer commentCount = baseMapper.selectCount(new LambdaQueryWrapper<Comment>().eq(Comment::getBlogId, blogId));
        //更新数据库该博文的评论数量
        blogService.update(new LambdaUpdateWrapper<Blog>().set(Blog::getCommentCount, commentCount).eq(Blog::getId, blogId));
        BlogForm form = new BlogForm();
        form.setId(blogId);
        form.setCommentCount(commentCount);
        //修改es该博文的评论数量
        esBlogService.update(form, false);
        //获取该博文下的最新的评论
        return listComment(blogId);
    }


}
